#ifndef THREAD_HPP
#define THREAD_HPP

#include <pthread.h>

#include <ctime>
#include <iostream>
#include <string>

typedef void (*callback_t)();

class Thread {
 private:
  static int num_;

 private:
  static void *Routine(void *args) {
    Thread *thread = static_cast<Thread *>(args);
    thread->Entery();
    return nullptr;
  }

 public:
  Thread(callback_t cb)
      : tid_(0), name_(""), start_timestamp_(0), isrunning_(false), cb_(cb) {}

  void Run() {
    name_ = "thread-" + std::to_string(num_++);
    start_timestamp_ = time(nullptr);
    isrunning_ = true;
    pthread_create(&tid_, nullptr, Routine, this);
  }

  void Join() {
    pthread_join(tid_, nullptr);
    isrunning_ = false;
  }

  void Entery() { cb_(); }

  void Detach() {
    if (isrunning_) {
      pthread_detach(tid_);
      isrunning_ = false;
    }
  }

  ~Thread() {
    if (isrunning_) {
      Join();
    }
  }
  std::string getName() { return name_; }
  uint64_t getStartTimeStamp() { return start_timestamp_; }
  bool isRunning() { return isrunning_; }

 private:
  pthread_t tid_;
  std::string name_;
  uint64_t start_timestamp_;
  bool isrunning_;

  callback_t cb_;
};
int Thread::num_ = 1;
#endif